package com.mall.order.biz.handler;

import com.mall.commons.tool.exception.BizException;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.dal.entitys.Stock;

import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.CartProductDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 扣减库存处理器
 * @Author： wz
 * @Date: 2019-09-16 00:03
 **/
@Component
@Slf4j
public class SubStockHandler extends AbstractTransHandler {

    @Autowired
    private StockMapper stockMapper;

    @Override
    public boolean isAsync() {
        return false;
    }

    @Override
    @Transactional
    public boolean handle(TransHandlerContext context) {
        CreateOrderContext createOrderContext = (CreateOrderContext) context;

        // 拿到从购物车传过来的订单信息,需要拿到productId和num信息，根据商品锁定库存量
        List<CartProductDto> dtoList = createOrderContext.getCartProductDtoList();
        // createOrderContext是由前端的requst传过来的 没有product信息，因此需要从dtolist中取出来
        List<Long> productIds = new ArrayList<>();
        for (CartProductDto cartProductDto : dtoList) {
            productIds.add(cartProductDto.getProductId());
        }

        // 将拿到的id进行排序（也可以不操作）
        productIds.sort(Long::compareTo);
        // 然后通过id 锁定商品的库存(即更新库存表的lock_count字段)
        List<Stock> stockList = stockMapper.findStocksForUpdate(productIds);
        if (stockList.isEmpty()) {
            throw new BizException("商品库存未初始化");
        }
        if (stockList.size() != productIds.size()) {
            throw new BizException("部分商品库存未初始化");
        }
        // 完成库存的锁定后，需要将商品的库存量更新(遍历每个商品，根据id和购买num去锁定)
        for (CartProductDto cartProductDto : dtoList) {
            Long productId = cartProductDto.getProductId();
            Long productNum = cartProductDto.getProductNum();

            // TODO 在更新之前需要判断购买数量是否大于限购数量 校验处已写过
            Stock stock = new Stock();
            stock.setItemId(productId);
            stock.setLockCount(productNum.intValue());
            stock.setStockCount(-productNum);

            stockMapper.updateStock(stock);
        }
        log.info("扣减库存锁定执行完成");
        return true;
    }
}